package com.dineroquegastar.urule.service;

import com.alibaba.fastjson.JSON;
import com.bstek.urule.Utils;
import com.bstek.urule.model.Label;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
import com.dineroquegastar.urule.constant.RespEnum;
import com.dineroquegastar.urule.entity.feature.mexico.*;
import com.dineroquegastar.urule.entity.feature.scoreCard.ScoreCardV1Fea;
import com.dineroquegastar.urule.entity.feature.scoreCard.ScoreCardV2Fea;
import com.dineroquegastar.urule.exception.BusinessException;
import com.dineroquegastar.urule.utils.jackson.JsonJacksonUtil;
import com.dineroquegastar.urule.vo.MXFirstReviewFlowResult;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 风控眼接口处理服务
 *
 * @author liuhai
 * @date 2021/3/28 1:55 PM
 */
@Service
@Slf4j
public class RiskEyeService {

    /**
     * 风控系统请求接收决策引擎处理返回决策结果
     * @param paramVO
     * @return
     */
    public MXFirstReviewFlowResult riskEyeResult(FeaturesCalculationRequest paramVO) {
        KnowledgeService knowledgeService = (KnowledgeService) Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
        KnowledgePackage kp = null;
        try {
            kp = knowledgeService.getKnowledge("demo/MX1001");//执行文件的知识包名
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            throw new BusinessException(RespEnum.SYS_ERR.getCode(), e.getMessage());
        }

        //将参数分类传入，方便决策系统选参
        /*传入参数 只有将参数传入决策引擎配置才可以生效*/
        FMachineFea fMachineFea = new FMachineFea();
        BeanUtils.copyProperties(paramVO,fMachineFea);
        String modelJson = paramVO.getModelJson();
        if (modelJson != null){
            Map<String, String> modelMap = JSON.parseObject(modelJson,Map.class);
            log.info("modelMap:{}",modelMap);
            fMachineFea.setScore(modelMap.get("dgstar") == null ? 0 : Float.parseFloat(modelMap.get("dgstar")));
            fMachineFea.setReloanScore(modelMap.get("reloan-dgstar") == null ? 0 : Float.parseFloat(modelMap.get("reloan-dgstar")));
            fMachineFea.setMxBXgb102Dpd7(modelMap.get("MxBXgb102Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("MxBXgb102Dpd7")));
            fMachineFea.setMxAXgb105Dpd7(modelMap.get("MxAXgb105Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("MxAXgb105Dpd7")));
            fMachineFea.setScoreV3(modelMap.get("MxBXgb101Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("MxBXgb101Dpd7")));
            fMachineFea.setMxAXgb106Dpd7(modelMap.get("MxAXgb106Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("MxAXgb106Dpd7")));
            fMachineFea.setMxbxgb103dpd7(modelMap.get("MxBXgb103Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("MxBXgb103Dpd7")));
            fMachineFea.setEcAxgb100Dpd7(modelMap.get("EcAxgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("EcAxgb100Dpd7")));
            fMachineFea.setPpAxgb100Dpd7(modelMap.get("PpAxgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpAxgb100Dpd7")));
            fMachineFea.setPpXgb101Dpd7(modelMap.get("PpXgb101Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpXgb101Dpd7")));
            fMachineFea.setPpBXgb100Dpd7(modelMap.get("PpBXgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpBXgb100Dpd7")));
            fMachineFea.setEcBXgb100Dpd7(modelMap.get("EcBXgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("EcBXgb100Dpd7")));
            fMachineFea.setPcBXgb100Dpd7(modelMap.get("PcBXgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PcBXgb100Dpd7")));
            fMachineFea.setPcAXgb100Dpd7(modelMap.get("PcAXgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PcAXgb100Dpd7")));
            fMachineFea.setCpAxgb100Dpd7(modelMap.get("CpAxgb100Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("CpAxgb100Dpd7")));
            fMachineFea.setCpAxgb101Dpd7(modelMap.get("CpAxgb101Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("CpAxgb101Dpd7")));
            fMachineFea.setPcXgb101Dpd7(modelMap.get("pcXgb101Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("pcXgb101Dpd7")));
            fMachineFea.setEcAxgb101Dpd7(modelMap.get("ecAxgb101Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("ecAxgb101Dpd7")));
            fMachineFea.setCpAxgb102Dpd7(modelMap.get("CpAxgb102Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("CpAxgb102Dpd7")));
            fMachineFea.setPpAxgb102Dpd7(modelMap.get("PpAxgb102Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpAxgb102Dpd7")));
            fMachineFea.setPpAxgb103Dpd7(modelMap.get("PpAxgb103Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpAxgb103Dpd7")));
            fMachineFea.setCpAxgb103Dpd7(modelMap.get("CpAxgb103Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("CpAxgb103Dpd7")));
            fMachineFea.setPpxgb105Dpd7(modelMap.get("ppxgb105Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("ppxgb105Dpd7")));
            fMachineFea.setPpAxgb301Dpd7(modelMap.get("PpAxgb301Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("PpAxgb301Dpd7")));
            fMachineFea.setEcAxgb102Dpd7(modelMap.get("EcAxgb102Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("EcAxgb102Dpd7")));
            fMachineFea.setA_EcXgb201Dpd7(modelMap.get("AECxgb201Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("AECxgb201Dpd7")));
            fMachineFea.setPcxgb102dpd7(modelMap.get("pcxgb102dpd7") == null ? 0 : Float.parseFloat(modelMap.get("pcxgb102dpd7")));
            fMachineFea.setA_CpXgb202Dpd7(modelMap.get("A_CpXgb202Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("A_CpXgb202Dpd7")));
            fMachineFea.setA_PpXgb201pd7(modelMap.get("A_PpXgb201pd7") == null ? 0 : Float.parseFloat(modelMap.get("A_PpXgb201pd7")));
            fMachineFea.setA_Pcxgb201Dpd7(modelMap.get("A_Pcxgb201Dpd7") == null ? 0 : Float.parseFloat(modelMap.get("A_Pcxgb201Dpd7")));
        }
        FAppListFea fAppListFea = new FAppListFea();
        BeanUtils.copyProperties(paramVO,fAppListFea);
        FEnvInfoRecordFea fEnvInfoRecordFea = new FEnvInfoRecordFea();
        BeanUtils.copyProperties(paramVO,fEnvInfoRecordFea);
        FPdlLoanFea fPdlLoanFea = new FPdlLoanFea();
        BeanUtils.copyProperties(paramVO,fPdlLoanFea);
        FPersonInfoFea fPersonInfoFea = new FPersonInfoFea();
        BeanUtils.copyProperties(paramVO,fPersonInfoFea);
        FPhoneBasicDataFea fPhoneBasicDataFea = new FPhoneBasicDataFea();
        BeanUtils.copyProperties(paramVO,fPhoneBasicDataFea);
        FPhoneBasicLoanFea fPhoneBasicLoanFea = new FPhoneBasicLoanFea();
        BeanUtils.copyProperties(paramVO,fPhoneBasicLoanFea);
        FPhoneContactFea fPhoneContactFea = new FPhoneContactFea();
        BeanUtils.copyProperties(paramVO,fPhoneContactFea);
        FPhoneLocationFea fPhoneLocationFea = new FPhoneLocationFea();
        BeanUtils.copyProperties(paramVO,fPhoneLocationFea);
        FSmsFea fSmsFea = new FSmsFea();
        BeanUtils.copyProperties(paramVO,fSmsFea);
        FTripartitefea fTripartitefea = new FTripartitefea();
        BeanUtils.copyProperties(paramVO,fTripartitefea);
        FContactInfoRecordFeaV2 fContactInfoRecordFeaV2 = new FContactInfoRecordFeaV2();
        BeanUtils.copyProperties(paramVO,fContactInfoRecordFeaV2);
        FRuleLoginOperate fRuleLoginOperate = new FRuleLoginOperate();
        BeanUtils.copyProperties(paramVO,fRuleLoginOperate);
        FRuleApplyLoanFea fRuleApplyLoanFea = new FRuleApplyLoanFea();
        BeanUtils.copyProperties(paramVO,fRuleApplyLoanFea);
        ScoreCardV1Fea scoreCardV1Fea = new ScoreCardV1Fea();
        BeanUtils.copyProperties(paramVO,scoreCardV1Fea);
        ScoreCardV2Fea scoreCardV2Fea = new ScoreCardV2Fea();
        FrankFeaRequest frankFea = paramVO.getFrankFea();
        BeanUtils.copyProperties(frankFea,scoreCardV2Fea);
        BeanUtils.copyProperties(paramVO,scoreCardV2Fea);
        FDeSmsFea fDeSmsFea = new FDeSmsFea();
        BeanUtils.copyProperties(paramVO.getDeSmsFea(),fDeSmsFea);
        FDeMultiFea fDeMultiFea = new FDeMultiFea();
        BeanUtils.copyProperties(paramVO,fDeMultiFea);

        /*单次调用*/
        KnowledgeSession kSession = KnowledgeSessionFactory.newKnowledgeSession(kp);
        kSession.insert(fMachineFea);
        kSession.insert(fAppListFea);
        //转换数据类型
        String env_info_record_base_station_3g_cell = paramVO.getEnv_info_record_base_station_3g_cell();
        fEnvInfoRecordFea.setEnv_info_record_base_station_3g_cell(Float.parseFloat(env_info_record_base_station_3g_cell));
        String Env_info_record_base_station_3g_lac = paramVO.getEnv_info_record_base_station_3g_lac();
        fEnvInfoRecordFea.setEnv_info_record_base_station_3g_lac(Float.parseFloat(Env_info_record_base_station_3g_lac));
        kSession.insert(fEnvInfoRecordFea);
        kSession.insert(fPdlLoanFea);
        kSession.insert(fPersonInfoFea);
        kSession.insert(fPhoneBasicDataFea);
        kSession.insert(fPhoneBasicLoanFea);
        kSession.insert(fPhoneContactFea);
        kSession.insert(fPhoneLocationFea);
        kSession.insert(fSmsFea);
        kSession.insert(fTripartitefea);
        kSession.insert(fContactInfoRecordFeaV2);
        kSession.insert(fRuleLoginOperate);
        kSession.insert(fRuleApplyLoanFea);
        kSession.insert(scoreCardV1Fea);
        scoreCardV2Fea.setF_frank_scoring_var_fea_age(Float.valueOf(String.valueOf(paramVO.getPerson_info_age())));
        scoreCardV2Fea.setF_frank_scoring_var_fea_sex(Float.valueOf(String.valueOf(paramVO.getPerson_info_sex())));
        scoreCardV2Fea.setF_frank_scoring_var_fea_mobile_len10(Float.valueOf(String.valueOf(paramVO.getPhone_contact_fea_mobile_len10())));
        scoreCardV2Fea.setF_frank_scoring_var_fea_mobile_start1_rate(paramVO.getMobile_start1_rate());
        scoreCardV2Fea.setF_frank_scoring_var_fea_phone_real_contact_ct(Float.valueOf(String.valueOf(paramVO.getPhone_basic_data_phone_real_contact_ct())));
        kSession.insert(scoreCardV2Fea);
        kSession.insert(fDeSmsFea);
        kSession.insert(fDeMultiFea);
        //此次迭代先不出去原有参数，下次迭代注释掉这个参数传入
        kSession.insert(paramVO);
        log.info("机审:getRule_apply_loan_fea_last1_apply_day_gap:{}," +
                        "getRule_apply_loan_fea_last1_apply_hour_gap:{},",
                fRuleApplyLoanFea.getRule_apply_loan_fea_last1_apply_day_gap(),
                fRuleApplyLoanFea.getRule_apply_loan_fea_last1_apply_hour_gap()
                );
       // log.info("serialId：{} paramVO：{} fMachineFea：{}",paramVO.getSerialId(),JsonJacksonUtil.toJson(paramVO), JsonJacksonUtil.toJson(fMachineFea));
//        Map<String, Object> parameter = new HashMap();
//        parameter.put("RESULT", Maps.newHashMap());

//        kSession.startProcess("MX_first_review",parameter);
        //kSession.startProcess("MX_first_review");
        //为空默认第一个流程
        /*执行指定的决策流ID*/
        kSession.startProcess(StringUtils.isBlank(paramVO.getDecisionProcessId()) ? "MX_first_review" : paramVO.getDecisionProcessId());

        /*获取执行结果*/
        Map<String, Object> parameter = kSession.getParameters();
        log.info("serialId：{} customerId：{} parameter result：{}",paramVO.getSerialId(),paramVO.getCustomerId(), JsonJacksonUtil.toJson(parameter));

        //组织结果
        return generateMXFirstReviewFlowResult(parameter);
    }

    private MXFirstReviewFlowResult generateMXFirstReviewFlowResult(Map<String, Object> parameter) {
        List<Object> list = new ArrayList<>();

        //----------------------------------墨西哥初审决策流结果----------------------------------------
        MXFirstReviewFlowResult flowResult = new MXFirstReviewFlowResult();

        Map<String, Object> resultMap = (Map<String, Object>) parameter.get("RESULT");
        //是否调用下一流程
        Integer is_next_process = resultMap.get("is_next_process") == null ? null : Integer.parseInt(resultMap.get("is_next_process").toString());
        flowResult.setIsNextProcess(is_next_process);

        //批核结果
        Integer decision_making_result = resultMap.get("decision_making_result") == null ? null : Integer.parseInt(resultMap.get("decision_making_result").toString());
        flowResult.setDecisionMakingResult(decision_making_result);

        //触碰的直拒规则
        String rule_reject = resultMap.get("rule_reject") == null ? null : resultMap.get("rule_reject").toString();
        flowResult.setRuleReject(rule_reject);

        //触碰的直批规则
        String rule_pass = resultMap.get("rule_pass") == null ? null : resultMap.get("rule_pass").toString();
        flowResult.setRulePass(rule_pass);

        //触碰的标签规则
        String rule_label = resultMap.get("rule_label") == null ? null : resultMap.get("rule_label").toString();
        flowResult.setRuleLabel(rule_label);

        //决策流姓名
        String decision_name = resultMap.get("decision_name") == null ? null : resultMap.get("decision_name").toString();
        flowResult.setDecisionName(decision_name);

        //首贷评分卡V1
        String score_card_v1 = resultMap.get("score_card_v1") == null ? null : resultMap.get("score_card_v1").toString();
        flowResult.setScoreCardV1(score_card_v1);

        //关键指标输出
        String key_features = resultMap.get("key_features") == null ? null : resultMap.get("key_features").toString();
        flowResult.setKeyFeatures(key_features);

        //------------------------------------墨西哥决策使用特征----------------------------------------
//        MXFeatures mxFeatures = new MXFeatures();
//
//        Map<String, Object> resultMap1 = (Map<String, Object>) parameter.get("Map_Characteristic");
//        //年龄
//        Integer BCIF001 = resultMap1.get("BCIF001") == null ? null : Integer.parseInt(resultMap.get("BCIF001").toString());
//        mxFeatures.setBCIF001(BCIF001);
//
//        //设备注册账号数量
//        Integer BCIF002 = resultMap1.get("BCIF002") == null ? null : Integer.parseInt(resultMap.get("BCIF002").toString());
//        mxFeatures.setBCIF002(BCIF002);
//
//        //所在行业
//        String BCIF003 = resultMap1.get("BCIF003") == null ? null : String.valueOf(resultMap.get("BCIF003").toString());
//        mxFeatures.setBCIF003(BCIF003);
//
//        //2天内设备登录用户数量
//        Integer BCIF004 = resultMap1.get("BCIF004") == null ? null : Integer.parseInt(resultMap.get("BCIF004").toString());
//        mxFeatures.setBCIF004(BCIF004);
//
//        //same_moble_ct和contact_ct的比值
//        Float BCIF005 = resultMap1.get("BCIF005") == null ? null : Float.parseFloat(resultMap.get("BCIF005").toString());
//        mxFeatures.setBCIF005(BCIF005);
//
//        //设备关联的逾期用户数
//        Integer BCIF006 = resultMap1.get("BCIF006") == null ? null : Integer.parseInt(resultMap.get("BCIF006").toString());
//        mxFeatures.setBCIF006(BCIF006);
//
//        //紧急联系人关联的逾期用户数
//        Integer BCIF007 = resultMap1.get("BCIF007") == null ? null : Integer.parseInt(resultMap.get("BCIF007").toString());
//        mxFeatures.setBCIF007(BCIF007);
//
//        //授信邮箱关联的逾期用户数
//        Integer BCIF008 = resultMap1.get("BCIF008") == null ? null : Integer.parseInt(resultMap.get("BCIF008").toString());
//        mxFeatures.setBCIF008(BCIF008);
//
//        //当前邮箱关联的逾期用户数
//        Integer BCIF009 = resultMap1.get("BCIF009") == null ? null : Integer.parseInt(resultMap.get("BCIF009").toString());
//        mxFeatures.setBCIF009(BCIF009);
//
//        //wifi_GPS关联用户数
//        Integer BCIF010 = resultMap1.get("BCIF010") == null ? null : Integer.parseInt(resultMap.get("BCIF010").toString());
//        mxFeatures.setBCIF010(BCIF010);
//
//        //相同紧急联系人匹配用户数
//        Integer BCIF011 = resultMap1.get("BCIF011") == null ? null : Integer.parseInt(resultMap.get("BCIF011").toString());
//        mxFeatures.setBCIF011(BCIF011);
//
//        //模型计算分数
//        Float BCIF012 = resultMap1.get("BCIF012") == null ? null : Float.parseFloat(resultMap.get("BCIF012").toString());
//        mxFeatures.setBCIF012(BCIF012);
//
//        //用户历史提单次数
//        Integer BCIF013 = resultMap1.get("BCIF013") == null ? null : Integer.parseInt(resultMap.get("BCIF013").toString());
//        mxFeatures.setBCIF013(BCIF013);
//
//        list.add(flowResult);

        return flowResult;
    }
}
